/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ui;

import control.MStockMidlet;
import java.util.Vector;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import listener.ICommandListener;
import listener.IKeyListener;

/**
 *
 * @author tho.hoang
 */
public class Table extends ACanvas {

    private Style cellHeadStyle, cellBodyStyle, cellFootStyle;
    private Vector items = null;
    private String errorMessage = "", footer = "";
    private String[] headers = null, footerRows = null;
    private String[][] dataItems = null;
    private int itemX = 0, itemY = 0;
    private int maxCols = -1, maxRows = -1;
    private int firstRowHeight = -1, firstColWidth = -1, footerHeight = 0;
    private int colsWidth = -1, rowsHeight = -1, cols = -1, rows = -1;
    private int curRow = -1, curCol = -1, startRow = -1, startCol = -1;
    private boolean firstPaint = true, hasData = false;

    public Table() {
    }

    public Table(Display display, MStockMidlet control, String title, String[] headers, Vector items, String footer, String errorMessage, Image background, Image icon) {
        super(display, control, title, background, icon);
        this.cellHeadStyle = control.getStyle().getCellHeadStyle();
        this.cellBodyStyle = control.getStyle().getCellBodyStyle();
        this.cellFootStyle = control.getStyle().getCellFootStyle();
        this.itemX = getItemX();
        this.itemY = getItemY();

        if (errorMessage != null) {
            this.errorMessage = errorMessage;
        }

        if (headers != null) {
            this.headers = headers;
        }

        if (items != null) {
            this.items = items;
        }

        if (footer != null) {
            this.footer = footer;
        }
    }

    public void paintItems(Graphics g) {
        if (firstPaint) {
            if (headers != null && headers.length > 1 && items != null) {
                initData();
            }
            firstPaint = false;
        }
        if (hasData == true && headers != null && headers.length > 1 && items != null && cols > 0) {
            int i = 0, j = 0, temp = 0;
            int x = itemX, y = itemY;

            // paint grid
            g.setColor(cellHeadStyle.getBgColor());
            g.fillRect(x, y, getItemWidth(), rowsHeight);
            g.fillRect(x, y, firstColWidth, (rows + 1) * rowsHeight);
            g.setColor(cellHeadStyle.getBorderColor());
            x = itemX;
            y = itemY;
            for (i = 0; i <= cols + 1; i++) {
                g.drawLine(x, y, x, y + (rows + 1) * rowsHeight);
                if (i == 0) {
                    x += firstColWidth;
                } else {
                    x += colsWidth;
                }
            }
            x = itemX;
            y = itemY;
            for (i = 0; i <= rows + 1; i++) {
                g.drawLine(x, y, x + getItemWidth(), y);
                y += rowsHeight;
            }

            // paint header (row and column)
            x = itemX + cellHeadStyle.getPadding().getLeft();
            y = itemY + cellHeadStyle.getPadding().getTop();
            getFont().getFontBold().drawString(g, dataItems[0][0], x, y, Graphics.TOP | Graphics.LEFT);
            x = itemX;
            y = itemY + rowsHeight;
            for (i = 0; i < rows; i++) {
                if (i + startRow == curRow) {
                    g.setColor(cellHeadStyle.getSelectedBgColor());
                    g.fillRect(x + 1, y + 1, firstColWidth - 1, rowsHeight - 1);
                }
                getFont().getFontBold().drawString(g, dataItems[i + startRow][0], x + cellHeadStyle.getPadding().getLeft(), y + cellHeadStyle.getPadding().getTop(), Graphics.TOP | Graphics.LEFT);
                y += rowsHeight;
            }
            x = itemX + firstColWidth;
            y = itemY;
            for (i = 0; i < cols; i++) {
                if (i + startCol == curCol) {
                    g.setColor(cellHeadStyle.getSelectedBgColor());
                    g.fillRect(x + 1, y + 1, colsWidth - 1, rowsHeight - 1);
                }
                getFont().getFontBold().drawString(g, dataItems[0][i + startCol], x + colsWidth - cellHeadStyle.getPadding().getRight(), y + cellHeadStyle.getPadding().getTop(), Graphics.TOP | Graphics.RIGHT);
                x += colsWidth;
            }

            // paint data cell
            y = itemY + rowsHeight;
            for (i = 0; i < rows; i++) {
                x = itemX + firstColWidth;
                for (j = 0; j < cols; j++) {
                    if (i + startRow == curRow && j + startCol == curCol) {
                        g.setColor(cellBodyStyle.getSelectedBgColor());
                        g.fillRect(x + 1, y + 1, colsWidth - 1, rowsHeight - 1);
                    }
                    getFont().getFontNormal().drawString(g, dataItems[i + startRow][j + startCol], x + colsWidth - cellHeadStyle.getPadding().getRight(), y + cellHeadStyle.getPadding().getTop(), Graphics.TOP | Graphics.RIGHT);
                    x += colsWidth;
                }
                y += rowsHeight;
            }

            // footer
            x = itemX + cellFootStyle.getPadding().getLeft();
            y = itemY + (rows + 1) * rowsHeight + cellFootStyle.getPadding().getTop();
            if (footer.length() > 0) {
                for (i = 0; i < footerRows.length; i++) {
                    getFont().getFontNormal().drawString(g, footerRows[i], x, y, Graphics.TOP | Graphics.LEFT);
                    y += getFont().getFontNormal().getHeight() + cellFootStyle.getRowHeight();
                }
            }

        } else {
//            String[] err = getNormalFont().splitWith(errorMessage, getItemWidth() - cellFootStyle.getPadding().getLeftAndRight());
            String[] err = new String[]{errorMessage};
            for (int e = 0; e < err.length; e++) {
                getFont().getFontNormal().drawString(g, err[e], itemX, itemY, Graphics.TOP | Graphics.LEFT);
                itemY += getFont().getFontNormal().getHeight() + cellFootStyle.getRowHeight();
            }
        }
    }

    private void initData() {
        int i = 0, j = 0, tempWidth = 0;
        String text = "";

        // init data
        this.maxCols = headers.length;
        this.maxRows = items.size() + 1; // 1: table header
        this.dataItems = new String[maxRows][maxCols];

        // init headers
        if (headers != null && headers.length > 1) {
            // first column
            this.firstColWidth = getFont().getFontBold().stringWidth(headers[0]);
            this.dataItems[0][0] = headers[0];

            // columns
            for (i = 1; i < headers.length; i++) {
                this.dataItems[0][i] = headers[i];
                tempWidth = getFont().getFontBold().stringWidth(headers[i]);
                if (tempWidth > colsWidth) {
                    this.colsWidth = tempWidth;
                }
            }
        }

        if (items != null && items.size() > 1) {
            this.hasData = true;

            // rows
            Vector item = null;
            for (i = 0; i < items.size(); i++) {
                item = (Vector) items.elementAt(i);
                if (item.size() < 2) {
                    this.hasData = false;
                    break;

                } else {
                    // first column
                    text = String.valueOf(item.elementAt(0));
                    this.dataItems[i + 1][0] = text;
                    tempWidth = getFont().getFontNormal().stringWidth(text);
                    if (tempWidth > firstColWidth) {
                        this.firstColWidth = tempWidth;
                    }
                    // columns
                    for (j = 1; j < item.size(); j++) {
                        text = String.valueOf(item.elementAt(j));
                        this.dataItems[i + 1][j] = text;
                        tempWidth = getFont().getFontNormal().stringWidth(text);
                        if (tempWidth > colsWidth) {
                            this.colsWidth = tempWidth;
                        }
                    }
                }
            }
        }

        if (footer.length() > 0) {
//            this.footerRows = getNormalFont().splitWith(footer, getItemWidth() - cellFootStyle.getPadding().getLeftAndRight());
            this.footerRows = new String[]{footer};
            tempWidth = footerRows.length;
            this.footerHeight = tempWidth * getFont().getFontNormal().getHeight() + (tempWidth - 1) * cellFootStyle.getRowHeight() + cellFootStyle.getPadding().getTopAndBottom();
        }

        colsWidth += cellHeadStyle.getPadding().getLeftAndRight();
        rowsHeight = getFont().getFontBold().getHeight() + cellHeadStyle.getPadding().getTopAndBottom();
        firstColWidth += cellHeadStyle.getPadding().getLeftAndRight();
        firstRowHeight = getFont().getFontBold().getHeight() + cellHeadStyle.getPadding().getTopAndBottom();

        cols = (getItemWidth() - firstColWidth) / colsWidth;
        rows = (getItemHeight() - 2 - firstRowHeight - footerHeight) / rowsHeight;
        // update width
        if (cols > maxCols - 1) {
            cols = maxCols - 1;
        }
        // scanning cols width
        tempWidth = getItemWidth() - colsWidth * cols - firstColWidth;
        colsWidth += tempWidth / (cols + 1);
        firstColWidth = getItemWidth() - colsWidth * cols;

        if (rows > maxRows - 1) {
            rows = maxRows - 1;
        }
        // init table
        curRow = 1;
        curCol = 1;
        startRow = 1;
        startCol = 1;
    }

    public void updateDataItems(Vector data) {
        for (int i = 1; i < dataItems.length; i++) {
            if (i - 1 < data.size()) {
                Vector item = (Vector) data.elementAt(i - 1);
                this.dataItems[i][0] = String.valueOf(item.elementAt(0));
                // columns
                for (int j = 1; j < item.size(); j++) {
                    this.dataItems[i][j] = String.valueOf(item.elementAt(j));
                }
            }
        }
    }

    public void keyPressed(int key) {
        ICommandListener commandListener = getCommandListener();

        if (key == getLeftSoftKey()) {
            if (commandListener != null && getSelectCommand() != null) {
                commandListener.commandAction(getSelectCommand());
            }

        } else if (key == getRightSoftKey()) {
            if (commandListener != null && getCancelCommand() != null) {
                commandListener.commandAction(getCancelCommand());
            }
        } else {
            IKeyListener keyListener = getKeyListener();
            switch (key) {
                case KEY_NUM0:
                case KEY_NUM1:
                case KEY_NUM2:
                case KEY_NUM3:
                case KEY_NUM4:
                case KEY_NUM5:
                case KEY_NUM6:
                case KEY_NUM7:
                case KEY_NUM8:
                case KEY_NUM9:
                case KEY_STAR:
                case KEY_POUND:
                case FIRE:
                    if (keyListener != null) {
                        keyListener.keyAction(key);
                    }
                    break;
                default:
                    if (!hasData) {
                        return;
                    }
                    
                    int gameAction = getGameAction(key);
                    boolean isRepaint = false;
                    if (gameAction == LEFT) {
                        if (curCol - 1 >= 1) {
                            curCol--;
                            isRepaint = true;
                            if (curCol < startCol) {
                                startCol--;
                            }
                        }

                    } else if (gameAction == RIGHT) {
                        if (curCol + 1 < headers.length) {
                            curCol++;
                            isRepaint = true;
                            if (curCol >= startCol + cols) {
                                startCol++;
                            }
                        }

                    } else if (gameAction == UP) {
                        if (curRow - 1 >= 1) {
                            curRow--;
                            isRepaint = true;
                            if (curRow < startRow) {
                                startRow--;
                            }
                        }

                    } else if (gameAction == DOWN) {
                        if (curRow + 1 <= items.size()) {
                            curRow++;
                            isRepaint = true;
                            if (curRow >= startRow + rows) {
                                startRow++;
                            }
                        }
                    }
                    if (isRepaint) {
                        repaint();
                    }
                    if (keyListener != null) {
                        keyListener.keyAction(gameAction);
                    }
                    break;
            }
        }
    }
}
